package org.example.websockettest.service.impl;

import org.example.websockettest.dao.User;
import org.example.websockettest.repository.UserRepository;
import org.example.websockettest.service.interfaces.UserService;
import org.example.websockettest.utils.JwtUtil;
import org.example.websockettest.utils.UserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RedisServiceImpl redisService;

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Value("${server.address}")
    private String serverAddress;

    @Value("${server.port}")
    private String serverPort;

    @Value("${spring.web.resources.static-locations}")
    private String staticLocations;

    @Autowired
    private ResourceLoader resourceLoader;

    public User register(String username, String password) {
        if (!UserUtils.validateUsername(username) || !UserUtils.validatePassword(password)) {
            throw new IllegalArgumentException("非法的用户名或密码");
        }
        if (userRepository.existsByUsername(username)) {
            throw new IllegalArgumentException("用户名已存在");
        }
        User user = new User();
        user.setUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        user.setUserId(UserUtils.generateUniqueId());
        user.setOnline(false);

        return userRepository.save(user);
    }

    public Map<String, String> login(String username, String password) {
        if (!UserUtils.validateUsername(username) || !UserUtils.validatePassword(password)) {
            throw new IllegalArgumentException("非法的用户名或密码");
        }
        User user = userRepository.findByUsername(username);
        if (user != null && passwordEncoder.matches(password, user.getPassword())) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", user.getUserId());
            String accessToken = JwtUtil.genAccessToken(claims);
            String refreshToken = JwtUtil.genRefreshToken(claims);
            Map<String, String> tokens = new HashMap<>();
            tokens.put("accessToken", accessToken);
            tokens.put("refreshToken", refreshToken);
            tokens.put("userId", String.valueOf(user.getUserId()));
            updateUserOnlineStatus(username, true);
            redisService.addUser(username);
            return tokens;
        }
        return null;
    }
    // 刷新token
    public String refreshAccessToken(String refreshToken) {
        try {
            Map<String, Object> claims = JwtUtil.parseToken(refreshToken);
            if (claims != null) {
                claims.put("userId", claims.get("userId"));
                return JwtUtil.genAccessToken(claims);
            }
        } catch (Exception e) {
            logger.error(String.valueOf(e));
        }
        return null;
    }

    public void updateUserOnlineStatus(String username, boolean isOnline) {
        User user = userRepository.findByUsername(username);
        if (user != null) {
            user.setOnline(isOnline);
            userRepository.save(user);
        }
    }

    public User findUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    public User findUserById(String userId) {
        return userRepository.findById(Long.parseLong(userId)).orElse(null);
    }

    public void logout(String userId) {
        User user = findUserById(userId);
        if (user != null) {
            updateUserOnlineStatus(user.getUsername(), false);
            redisService.removeUser(user.getUsername());
        }
    }

    public boolean updateUserInfo(String userId, String email, String avatar, String bio, String className, String school) {
        User user = findUserById(userId);
        if (user != null) {
            if (email != null) user.setEmail(email);
            if (avatar != null) user.setAvatar(avatar);
            if (bio != null) user.setBio(bio);
            if (className != null) user.setClassName(className);
            if (school != null) user.setSchool(school);
            userRepository.save(user);
            return true;
        }
        return false;
    }

    public String saveAvatar(MultipartFile file, String userId) {
        try {
            String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
            String userUploadDir = resourceLoader.getResource("classpath:/static/files/upload/").getFile().getAbsolutePath() + "/" + userId;
            String filePath = userUploadDir + "/" + fileName;

            Files.createDirectories(Paths.get(userUploadDir));

            file.transferTo(new File(filePath));

            return "http://" + serverAddress + ":" + serverPort + "/files/upload/" + userId + "/" + fileName;
        } catch (IOException e) {
            logger.error("头像保存失败: ", e);
            return null;
        }
    }
}
